#include <iostream>
#include "../Headers/log.h"
#include "email.h"

using namespace TOB;

Email::Email(Nameserver::IP nsip, std::string &username, std::string &password):
  AuthRequired(nsip, username, password) {
  // Resolve address
  connected = false;
  std::string addr;
  Nameserver::convertIP(nsip, addr);
  Nameserver ns(addr);
  Nameserver::IP emip;
  if((code = ns.requestAddress(Server::Email, emip)) != Code::Okay) {
    return;
  }

  // Connect
  Nameserver::convertIP(emip, addr);
  clnt = clnt_create(addr.c_str(), EM_PROG, EM_VER, "tcp");
  if(clnt == NULL) {
    return;
  }
  connected = true;
}


Email::~Email() {
  if(connected && clnt != NULL) {
    clnt_destroy(clnt);
  }
}


Code::Type Email::getNextSubject(uint32 letterId, std::string &header) {
  if(code != Code::Okay) { return code; }
  if(!connected) { return Code::EM_DoesntRespond; }
  
  em_getNextSubjectRes *res;
  em_readParam param;
  applyAuthr(param.authr);
  param.letterId = letterId;

  res = _getnextsubject_1(&param, clnt);
  if(res == NULL) { return Code::EM_DoesntRespond; }
  header = std::string(res->header);
  return (Code::Type)res->code;
} 


Code::Type Email::readLetter(uint32 letterId, std::string &body) {
  if(code != Code::Okay) { return code; }
  if(!connected) { return Code::EM_DoesntRespond; }

  Log::event("Trying to read mail");
  em_readLetterRes *res;
  em_readParam param;
  applyAuthr(param.authr);
  param.letterId = letterId;

  res = _readletter_1(&param, clnt);
  if(res == NULL) { return Code::EM_DoesntRespond; }
  body = std::string(res->body);
  return (Code::Type)res->code;
}


Code::Type Email::sendLetter(std::string &header, std::string &body) {
  if(code != Code::Okay) { return code; }
  if(!connected) { return Code::EM_DoesntRespond; }

  Log::event("Trying to send mail");
  em_sendLetterParam param;
  applyAuthr(param.authr);
  std::string tmp = header.substr(0, HEADERLENGTH-1);
  memcpy(param.header, tmp.c_str(), tmp.size()+1);
  tmp = body.substr(0, BODYLENGTH-1);
  memcpy(param.body, tmp.c_str(), tmp.size()+1);

  unsigned int *code = _sendletter_1(&param, clnt);
  if(!code) { return Code::EM_DoesntRespond; }
  return (Code::Type)*code;
}


Code::Type Email::expandMail() {
  if(code != Code::Okay) { return code; }
  if(!connected) { return Code::EM_DoesntRespond; }
  em_authr authr;
  applyAuthr(authr);
  unsigned int *code = _expandmail_1(&authr, clnt);
  if(!code) { return Code::EM_DoesntRespond; }
  return (Code::Type)*code;
}


void Email::applyAuthr(em_authr &authr) {
  authr.nsip = nsip;
  std::string tmp = username.substr(0, LOGINLENGTH-1);
  memcpy(authr.username, tmp.c_str(), tmp.size()+1);
  tmp = password.substr(0, LOGINLENGTH-1);
  memcpy(authr.password, tmp.c_str(), tmp.size()+1);
}
